home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / amiga / ujoin101.lzh / FileScan.c next >
C/C++ Source or Header  |  1990-03-12  |  5KB  |  184 lines

  1. #ifdef AZTEC_C
  2.  
  3. /* Build an expanded list of filenames from a filename argument list. */
  4.  
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9.  
  10. /*  The ListInfo structure tracks our filename list building process. */
  11.  
  12. typedef struct ListInfo {
  13.     char        **theList;
  14.     int         slotCount;          /* number of slots in the list. */
  15.     int         entryCount;         /* number of slots filled */
  16.     } ListInfo;
  17.  
  18. /*  FUNCTION
  19.  *      AddFile - add a filename to the filename list.
  20.  *
  21.  *  SYNOPSIS
  22.  *      static int AddFile(ListInfo *fileList, const char *theFile);
  23.  *
  24.  *  DESCRIPTION
  25.  *      AddFile attempts to add <theFile> to the filename list. The list will be
  26.  *      expanded if necessary. 
  27.  *
  28.  *      AddFile returns zero if successful or 1 on error.
  29.  */
  30.  
  31. static int
  32. AddFile(ListInfo *fileList, char *theFile)
  33. {
  34.     char    *fName;                 /* for a copy of theFile */
  35.     char    **newList;
  36.     int     newCount;
  37.     size_t  newSize;
  38.  
  39.     if (fileList->entryCount >= fileList->slotCount) { /* Expand the list? */
  40.         newCount = fileList->slotCount + 50;
  41.         /* Note that malloc is used rather than realloc, since I think realloc is
  42.          * broken.
  43.          */
  44.         newSize = sizeof(char *) * newCount;
  45.         newList = malloc(newSize);
  46.         if (newList == NULL) return 1;   /* Error! */
  47.         fileList->slotCount = newCount;
  48.         if (fileList->theList) {
  49.             /* Copy old stuff to new list. */
  50.             memcpy(newList, fileList->theList, newSize);
  51.             /* Dispose of the old list. */
  52.             free(fileList->theList);
  53.         }
  54.         fileList->theList = newList;
  55.     }
  56.  
  57.     fName = malloc(strlen(theFile)+1);
  58.     if (! fName) return 1;
  59.     strcpy(fName, theFile);
  60.     fileList->theList[fileList->entryCount++] = fName;
  61.     return 0;
  62. }
  63.  
  64. /*  FUNCTION
  65.  *      TestWild - test a file specification for wildcard content.
  66.  *
  67.  *  SYNOPSIS
  68.  *      static int TestWild(const char *fileName);
  69.  *
  70.  *  DESCRIPTION
  71.  *      TestWild scans <fileName>, looking for wildcard characters (?, *). If found,
  72.  *      TestWild returns 1. If not found, TestWild returns 0.
  73.  *
  74.  *      TestWild is provided to prevent unnecessary calls to scdir().
  75.  */
  76.  
  77. static int
  78. TestWild(char *fileName)
  79. {
  80.     char    *p, c;
  81.  
  82.     for (p = fileName; c = *p++;)
  83.         if (c == '?' || c == '*') return 1;
  84.     return 0;
  85. }
  86.  
  87. /*  Note: Lattice users can replace this with stricmp, but this is small enough to
  88.  *  just leave it in here.
  89.  */
  90.  
  91. /*  FUNCTION
  92.         scmpi - perform a case-insensitive string compare.
  93.  
  94.     SYNOPSIS
  95.         int scmpi(const char *s1, const char *s2);
  96.  
  97.     DESCRIPTION
  98.         Strings <s1> and <s2> are compared, ignoring differences in case.
  99.         A result code is returned according to the following:
  100.             0   => strings match
  101.            <0   => s1 < s2
  102.            >0   => s1 > s2
  103. */
  104.  
  105. static int
  106. scmpi(const char *s1, const char *s2)
  107. {
  108.     int c1, c2, cd;
  109.  
  110.     do {
  111.         c1 = tolower(*s1++);
  112.         c2 = tolower(*s2++);
  113.         if (cd = (c1 - c2)) break;
  114.     } while (c1 && c2);
  115.  
  116.     return cd;
  117. }
  118.  
  119. /*  FUNCTION
  120.  *      Compare - perform case-insensitive compare of two filename strings.
  121.  *
  122.  *  SYNOPSIS
  123.  *      static int Compare(const void *a, const void *b);
  124.  *
  125.  *  DESCRIPTION
  126.  *      Compare simply provides an interface between qsort() and a string
  127.  *      comparison routine. It returns the result of the string comparison.
  128.  */
  129.  
  130. static int
  131. Compare(const void *a, const void *b)
  132. {
  133.     return scmpi(*(char **)a, *(char **)b);
  134. }
  135.  
  136. /*  FUNCTION
  137.  *      FileScan - scan, expand and optionally sort a file specification list.
  138.  *
  139.  *  SYNOPSIS
  140.  *      char **FileScan(char **rawList, int rawCount, int *newCount; 
  141.  *                      int sortFiles);
  142.  *
  143.  *  DESCRIPTION
  144.  *      FileScan treats each entry in <rawList> as a file specification and
  145.  *      attempts to expand it into multiple filenames. The number of entries
  146.  *      in <rawList> is defined by <rawCount>. If successful, FileScan will
  147.  *      return a pointer to a new list of filenames, passing the number of entries
  148.  *      via <newCount>. If <sortFiles> is non-zero, the list will be sorted.
  149.  *
  150.  *      If FileScan is unable to perform an allocation, NULL is returned.
  151.  */
  152.  
  153. char **
  154. FileScan(char **rawList, int rawCount, int *newCount, int sortFiles)
  155. {
  156.     ListInfo    fileList;           /* Stack-based for reentrancy. */
  157.     int         rawIndex = 0;
  158.     char        *rawName;
  159.     char        *theName;
  160.     
  161.     fileList.theList = NULL;        /* Initialize the list structure. */
  162.     fileList.slotCount = 0;
  163.     fileList.entryCount = 0;
  164.  
  165.     while (rawIndex < rawCount) {
  166.         rawName = rawList[rawIndex++];
  167.         if (TestWild(rawName)) {
  168.             while (theName = scdir(rawName)) /* scdir() is not reentrant... */
  169.                 if (AddFile(&fileList, theName)) return NULL;
  170.         }
  171.         else
  172.             if (AddFile(&fileList, rawName)) return NULL;
  173.     }
  174.  
  175.     *newCount = fileList.entryCount;
  176.     if (fileList.theList && sortFiles) {
  177.         qsort(fileList.theList, fileList.entryCount, sizeof(char *), Compare);
  178.     }
  179.     return fileList.theList;
  180. }
  181. #else
  182. #include <Not_Implemented_For_Lattice>
  183. #endif
  184.